#include "PreCompile.hpp"
#include "XmlUtilsTests.hpp"
#include "UtilsTests.hpp"
#include "InStreamTests.hpp"
#include "OutStreamTests.hpp"
#include "GPathExtTests.hpp"
#include "SuperGlobTests.hpp"
#include "TmpAllocatorTests.hpp"
#include "AsyncRingBufferTests.hpp"
#include "StringBuilderTests.hpp"
#include "NamedObjectTests.hpp"
#include "WeakPtrTests.hpp"

#ifdef WINDOWS
#include <crtdbg.h>
#endif

int main()
{
#ifdef WINDOWS
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

  try
  {
    BuildNG::init_shared();

    BuildNG::TmpPoolTests::test();

    BuildNG::TmpArrayTests::test_grow();
    BuildNG::TmpArrayTests::test_remove();
    BuildNG::TmpArrayTests::test_array_copy_ctor();
    BuildNG::TmpArrayTests::test_assignment_operator();
    BuildNG::TmpArrayTests::test_elements_ctor_dtor();
    BuildNG::TmpArrayTests::test_replace();

    BuildNG::InStreamTests::test_read_buffer();
    BuildNG::InStreamTests::test_read_uint8();
    BuildNG::InStreamTests::test_read_uint16();
    BuildNG::InStreamTests::test_read_uint32();
    BuildNG::InStreamTests::test_read_bool();
    BuildNG::InStreamTests::test_read_line_simple();
    BuildNG::InStreamTests::test_read_line_special_cases();
    BuildNG::InStreamTests::test_mixed_newline_chars();
    BuildNG::InStreamTests::test_invalid_utf8_line();
    BuildNG::InStreamTests::test_std_instream();

    BuildNG::OutStreamTests::test_write_buffer();
    BuildNG::OutStreamTests::test_write_uint8();
    BuildNG::OutStreamTests::test_write_uint16();
    BuildNG::OutStreamTests::test_write_uint32();
    BuildNG::OutStreamTests::test_write_bool();
    BuildNG::OutStreamTests::test_write_line();
    BuildNG::OutStreamTests::test_std_out_stream();

    //BuildNG::XmlUtilsTests xml_utils_tests;
    BuildNG::UtilsTests::test_int_to_str();
    BuildNG::UtilsTests::test_try_parse_int();
    BuildNG::UtilsTests::test_parse_command_line_args();
    BuildNG::UtilsTests::test_compare_string_begin();
    BuildNG::UtilsTests::test_trim();
    BuildNG::UtilsTests::test_get_next_pow2();
    BuildNG::UtilsTests::test_get_next_pow2_size_t();

    BuildNG::SuperGlobTests::test_tokenize_glob_pattern();
    BuildNG::SuperGlobTests::test_glob_compare();
    BuildNG::SuperGlobTests::test_glob_with_fake_tree();

    BuildNG::GPathExtTests::test_get_relative_path();
    BuildNG::GPathExtTests::test_canonicalize_path();
    BuildNG::GPathExtTests::test_split_into_elements();
    BuildNG::GPathExtTests::test_split_into_elements_empty_str();

    BuildNG::AsyncRingBufferTests::test_sync_aligned_size();
    BuildNG::AsyncRingBufferTests::test_sync_unaligned_size();
    BuildNG::AsyncRingBufferTests::test_dtor_non_empty_buffer();
    BuildNG::AsyncRingBufferTests::test_wrap_around1();
    BuildNG::AsyncRingBufferTests::test_wrap_around2();
    BuildNG::AsyncRingBufferTests::test_pop_all();
    BuildNG::AsyncRingBufferTests::test_multiple_pushing_threads();

    BuildNG::StringBuilderTests::test_string_builder();
    BuildNG::StringBuilderTests::test_clear();
    BuildNG::StringBuilderTests::test_pop_end();

    BuildNG::NamedObjectTests::test_name_change_signals();
    BuildNG::NamedObjectTests::test_cancel_name_change();
    BuildNG::NamedObjectTests::test_named_collection_simple();
    BuildNG::NamedObjectTests::test_name_collision();
    BuildNG::NamedObjectTests::test_rename_in_collection();
    BuildNG::NamedObjectTests::test_rename_to_same_name();

    BuildNG::WeakPtrTests::basic_test();
    BuildNG::WeakPtrTests::test_acquired_kept_alive();
    BuildNG::WeakPtrTests::test_copy_weakptr();
    BuildNG::WeakPtrTests::test_assign_weakptr();

    BuildNG::shutdown_shared();

    return 0;
  }
  catch(const std::exception &err)
  {
    std::cerr << "An unhandled exception has been thrown: " << err.what() << std::endl;
    assert(!"Unhandled exception");
    return -1;
  }
}

